package com.ncmmall.mall.controller.business.marketing.groupbooking;

import com.alibaba.excel.metadata.BaseRowModel;
import com.ncmmall.application.business.goods.GoodsApplication;
import com.ncmmall.application.securitys.logs.OperationLogApplication;
import com.feijin.commons.exceptions.IllegalRequestException;
import com.feijin.commons.lang.Dates;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.business.goods.Goods;
import com.ncmmall.domain.business.goods.QGoods;
import com.ncmmall.domain.business.goods.channel.GoodsChannel;
import com.ncmmall.domain.business.goods.channel.QGoodsChannel;
import com.ncmmall.domain.business.marketing.seckill.GroupBookingGoods;
import com.ncmmall.domain.business.merchant.MerchantGoodsChannel;
import com.ncmmall.domain.business.merchant.QMerchantGoodsChannel;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.mall.controller.securitys.shiro.Securitys;
import com.ncmmall.mall.params.GroupBookingDTO;
import com.ncmmall.mall.params.PageParams;
import com.ncmmall.mall.utils.excel.ExcelUtil;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 拼团活动
 *
 * @author linxs
 * @date 2020-02-03 14:35
 */
@Controller
@RequestMapping(value = "/merchant/groupBooking")
@Slf4j
public class GroupBookingController {

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private GoodsApplication goodsApplication;

    @Autowired
    private OperationLogApplication logApplication;

    /**
     * 商品列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    private String list(Model model, PageParams pageParams, Goods goods) {

        WebUser merchant = Securitys.currentUser();

        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = new HashMap<>();
        params.put("id", merchant.getId());

        QueryPage<Goods> page;
        if (goods.getGroupBookingStatus() == 6) {
            QueryPage<GroupBookingGoods> page2 = queryChannelService.findPage("select b from GroupBookingGoods b where b.goods.merchant.id = :id order by b.createTime desc", pageRequest.setParams(params), GroupBookingGoods.class);
            List<Goods> goodsList = new ArrayList<>();
            for (GroupBookingGoods groupBookingGoods : page2.getResult()) {
                Goods g = groupBookingGoods.getGoods();
                g.setGroupBookingPrice(groupBookingGoods.getGroupBookingPrice());
                g.setGroupBookingStore(groupBookingGoods.getGroupBookingStore());
                g.setGroupBookingCondition(groupBookingGoods.getGroupBookingCondition());
                g.setGroupBookingTotal(groupBookingGoods.getGroupBookingTotal());
                g.setGroupBookingBeginTime(groupBookingGoods.getGroupBookingBeginTime());
                g.setGroupBookingEndTime(groupBookingGoods.getGroupBookingEndTime());
                g.setGroupBookingLimit(groupBookingGoods.getGroupBookingLimit());
                g.setSalesVolume(groupBookingGoods.getGroupBookingSalesVolume());
                g.setGroupBookingStatus(groupBookingGoods.getGroupBookingStatus());
                goodsList.add(g);
            }
            page = new QueryPage<>(page2.getTotalCount(), goodsList, page2.getPageNo(), page2.getPageSize());
        } else {
            String hql = builderSQL("select u from Goods u where u.merchant.id = :id and u.marketingType = 4 ", params, goods);
            page = queryChannelService.findPage(hql, pageRequest.setParams(params), Goods.class);
        }

        List<GoodsChannel> channels = queryChannelService.findAll(QMerchantGoodsChannel.merchantGoodsChannel.merchant.id.eq(merchant.getId()), MerchantGoodsChannel.class).stream().map(MerchantGoodsChannel::getChannel).collect(Collectors.toList());

        model.addAttribute("page", page).addAttribute("params", goods).addAttribute("channels", channels);

        return "merchant/marketing/groupBooking/list";
    }

    /**
     * 导出Excel
     */
    @RequestMapping(value = "/exports", method = RequestMethod.GET)
    public void exports(HttpServletResponse response, Goods goods) {
        try {
            Map<String, Object> map = Maps.newHashMap();
            String hql = builderSQL("select u from Goods u where u.merchant.id = :id and u.marketingType = 4 ", map, goods);
            map.put("id", Securitys.currentUser().getId());

            List<Goods> result = queryChannelService.findAll(hql, map, Goods.class);
            List<BaseRowModel> data = new ArrayList<>(result.size());

            for (Goods goods1 : result) {
                String statusString = "";
                if (goods1.getGroupBookingStatus() == 1) {
                    statusString = "待上架";
                } else if (goods1.getGroupBookingStatus() == 2) {
                    statusString = "审核中";
                } else if (goods1.getGroupBookingStatus() == 3) {
                    statusString = "审核通过";
                } else if (goods1.getGroupBookingStatus() == 4) {
                    statusString = "审核不通过";
                } else if (goods1.getGroupBookingStatus() == 5) {
                    statusString = "活动开始";
                } else if (goods1.getGroupBookingStatus() == 6) {
                    statusString = "活动结束";
                } else if (goods1.getGroupBookingStatus() == 7) {
                    statusString = "下架";
                }
                GroupBookingDTO bargainDTO = new GroupBookingDTO()
                        .setGoodsNo(goods1.getGoodsNo())
                        .setGoodsName(goods1.getName())
                        .setActivityPrice(String.valueOf(goods1.getGroupBookingPrice()))
                        .setActivityStock(String.valueOf(goods1.getGroupBookingStore()))
                        .setSaleNumber(String.valueOf(goods1.getGroupBookingSalesVolume()))
                        .setTime(goods1.getGroupBookingBeginTime() + " - " + goods1.getGroupBookingEndTime())
                        .setStatus(statusString);
                data.add(bargainDTO);
            }

            ExcelUtil.writeExcel(response, data, "拼团活动" + Dates.transDateToStr(new Date()), "sheet", new GroupBookingDTO());

        } catch (Exception e) {
            log.error("[导出异常]", e);
        }
    }


    /**
     * 选择拼团商品页面
     */
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    private String create(Model model) {

        model.addAttribute("_method", "POST").addAttribute("goods", new Goods());

        return "merchant/marketing/groupBooking/form";
    }


    /**
     * 详情
     */
    @RequestMapping(value = "/{id}/detail", method = RequestMethod.GET)
    private String detail(Model model, @PathVariable("id") long id) {

        Goods goods = queryChannelService.findOne(QGoods.goods.id.eq(id), Goods.class);

        model.addAttribute("goods", goods);

        return "merchant/marketing/groupBooking/detail";

    }


    /**
     * 添加拼团商品页面
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    private String create(Model model, @RequestParam("id") long id) {

        Goods goods = queryChannelService.findOne(QGoods.goods.id.eq(id), Goods.class);
        model.addAttribute("goods", goods).addAttribute("_method", "PUT");

        return "merchant/marketing/groupBooking/form";

    }

    /**
     * 添加拼团商品
     */
    @RequestMapping(value = "/create", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> modifyStore(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, Goods goods) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            goodsApplication.addGroupBookingGoods(goods);
            logApplication.eventOfMerchant(Securitys.currentUser(), "添加拼团商品", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {

            log.error("[添加拼团商品异常]", e);
            return ImmutableMap.of("status", false);

        }
    }

    /**
     * 删除
     */
    @RequestMapping(value = "/remove", method = RequestMethod.DELETE)
    @ResponseBody
    private Map<String, Object> remove(@RequestHeader("X-Requested-With") String requestWith, Goods goods) {

        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            goodsApplication.removeGroupBooking(goods);


            return ImmutableMap.of("status", true);

        } catch (Exception e) {

            log.error("[删除预售活动异常]", e);
            return ImmutableMap.of("status", false);

        }
    }

    /**
     * 提交审核
     */
    @RequestMapping(value = "/applyProcess", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> applyProcess(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            Goods goods = queryChannelService.findOne(QGoods.goods.id.eq(id), Goods.class);

            goodsApplication.applyProcessGroupBooking(goods);
            logApplication.eventOfMerchant(Securitys.currentUser(), "提交拼团商品审核", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {

            log.error("[提交拼团商品审核异常]", e);
            return ImmutableMap.of("status", false);

        }
    }

    /**
     * 下架
     */
    @RequestMapping(value = "/soldout", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> soldout(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            Goods goods = queryChannelService.findOne(QGoods.goods.id.eq(id), Goods.class);

            goodsApplication.soldoutGroupBooking(goods);
            logApplication.eventOfMerchant(Securitys.currentUser(), "下架拼团商品", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {

            log.error("[下架拼团商品异常]", e);
            return ImmutableMap.of("status", false);

        }
    }

    /**
     * 选择商品设置为拼团
     */
    @RequestMapping(value = "/chooseGoods", method = RequestMethod.GET)
    private String chooseGoods(Model model, PageParams pageParams, Goods goods) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();
        params.put("id", Securitys.currentUser().getId());
        String hql = builderGoodsSQL("select u from Goods u where u.merchant.id = :id and u.status = 3 and u.marketingType = 0 ", params, goods);
        QueryPage<Goods> page = queryChannelService.findPage(hql, pageRequest.setParams(params), Goods.class);

        model.addAttribute("page", page)
                .addAttribute("params", goods)
                .addAttribute("channels", queryChannelService.findAll("select c from GoodsChannel c where c.deleteStatus = 0 and  c.level = 1 and c.status = 1 ", GoodsChannel.class));

        return "merchant/marketing/groupBooking/chooseGoods";
    }

    private String builderGoodsSQL(String sql, Map<String, Object> params, Goods goods) {
        if (goods.getIsSupplier() > 0) {
            sql += " and u.isSupplier = 1 ";
        } else {
            sql += " and u.isSupplier = 0 ";
        }

        if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getId() > 0) {
            goods.setGoodsChannel(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getId());

        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getId() > 0) {
            goods.getGoodsChannel().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getId());

        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getParent().getId() > 0) {
            goods.getGoodsChannel().getParent().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getParent().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.parent.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getParent().getId());
        }

        if (goods.getMerchant() != null && goods.getMerchant().getId() > 0) {
            sql += " and u.merchant.id = :merchantId ";
            params.put("merchantId", goods.getMerchant().getId());
        }

        if (goods.getStatus() > 0) {
            sql += " and u.status = :status ";
            params.put("status", goods.getStatus());
        } else {
            sql += " and u.status in (3,6) ";
        }

        if (!Strings.isNullOrEmpty(goods.getGoodsNo())) {
            sql += " and u.goodsNo like :goodsno ";
            params.put("goodsno", "%" + goods.getGoodsNo() + "%");
        }

        if (!Strings.isNullOrEmpty(goods.getName())) {
            sql += " and u.name like :name ";
            params.put("name", "%" + goods.getName() + "%");
        }


        if (!Strings.isNullOrEmpty(goods.getOrderByCreateTime())) {
            sql += " order by u.createTime " + goods.getOrderByCreateTime();
        } else if (!Strings.isNullOrEmpty(goods.getOrderByPrice())) {
            sql += " order by u.defaultPrice " + goods.getOrderByPrice();
        } else if (!Strings.isNullOrEmpty(goods.getOrderByStore())) {
            sql += " order by u.store " + goods.getOrderByStore();
        } else if (!Strings.isNullOrEmpty(goods.getOrderBySalesVolume())) {
            sql += " order by u.salesVolume " + goods.getOrderBySalesVolume();
        } else {
            sql += " order by u.createTime desc ";
        }

        return sql;
    }


    /**
     * 条件筛选
     */
    private String builderSQL(String sql, Map<String, Object> params, Goods goods) {

        if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getId() > 0) {
            goods.setGoodsChannel(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getId());

        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getId() > 0) {
            goods.getGoodsChannel().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getId());

        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getParent().getId() > 0) {
            goods.getGoodsChannel().getParent().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getParent().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.parent.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getParent().getId());
        }


        if (goods.getGroupBookingStatus() > 0) {
            sql += " and u.groupBookingStatus = :status ";
            params.put("status", goods.getGroupBookingStatus());
        }

        if (!Strings.isNullOrEmpty(goods.getGoodsNo())) {
            sql += " and u.goodsNo like :goodsno ";
            params.put("goodsno", "%" + goods.getGoodsNo() + "%");
        }

        if (!Strings.isNullOrEmpty(goods.getName())) {
            sql += " and u.name like :name ";
            params.put("name", "%" + goods.getName() + "%");
        }

        if (!Strings.isNullOrEmpty(goods.getOrderByCreateTime())) {
            sql += " order by u.createTime " + goods.getOrderByCreateTime();
        } else if (!Strings.isNullOrEmpty(goods.getOrderByPrice())) {
            sql += " order by u.groupBookingPrice " + goods.getOrderByPrice();
        } else if (!Strings.isNullOrEmpty(goods.getOrderByStore())) {
            sql += " order by u.groupBookingStore " + goods.getOrderByStore();
        } else if (!Strings.isNullOrEmpty(goods.getOrderBySalesVolume())) {
            sql += " order by u.salesVolume " + goods.getOrderBySalesVolume();
        } else {
            sql += " order by u.createTime desc ";
        }

        return sql;
    }

    /**
     * 批量提交审核
     */
    @RequestMapping(value = "/allApplyCheck", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> disables(@RequestHeader("X-Requested-With") String requestWith, String data) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalArgumentException("request must be ajax");
            }

            goodsApplication.allApplyCheck(data);
            return ImmutableMap.of("status", true, "message", "提交成功");

        } catch (Exception e) {

            log.error("批量提交审核异常", e);
            return ImmutableMap.of("status", false, "message", "提交异常");

        }
    }
}
